<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="/fengMap/libs/js/fengmap.map.min.js"></script>
    <script src="/fengMap/libs/js/fengmap.analyser.min.js"></script>
    <script src="/fengMap/libs/js/fengmap.plugin.navi.min.js"></script>
    <script src="/fengMap/libs/js/jquery-3.6.1.min.js"></script>
    <link rel="stylesheet" href="/fengMap/libs/css/layui.css">
    <link rel="stylesheet" href="/fengMap/libs/css/index.css">
    <link rel="stylesheet" href="/fengMap/libs/css/sidewalk.css">
    <title>地图导航</title>
</head>

<body>
    <div class="guide-box">
        <div class="map-mask">
            <div class="loading"></div>
        </div>
        <div class="guide-search">
            <input type="text" @input="keywordInput" id="queryId" class="ipt_search" placeholder="请输入搜索关键词"
                placeholder-style="color: #999">
            <div class="search" onclick="queryItem()">搜索</div>
            <div class="clear" onclick="clearQuery()">清除</div>
            <div class="query-top-list"></div>
        </div>
        <div id="fengmap"></div>
        <div class="guide-line">
            <div class="guide-main">
                <div class="guide-point guide-start">
                    <input type="text" placeholder="请输入起点" id="startInput" />
                    <img src="/fengMap/assets/add.png" alt="" class="change-img" onclick="addLine()" />
                </div>
                <div class="middle-box">
                    <!-- <div class="guide-point guide-middle">
                        <input type="text" placeholder="请输入途经点名称" class="waypoint" />
                        <img src="./fengMap/assets/reduce.png" alt="" class="change-img" @click="reduceLine(index)" />
                    </div> -->
                </div>
                <div class="guide-point guide-end">
                    <input type="text" placeholder="请输入终点" id="endInput" />
                </div>
                <img src="/fengMap/assets/exchange-img.png" alt="" class="exchange-img" onclick="onExchange()" />
            </div>
            <div class="line-btns">
                <div class="btn">
                    关闭
                </div>
                <div class="btn btn-operate" onclick="pauseOrPlay()">
                    暂停
                </div>
                <div class="btn btn-clear" onclick="clearAll()">
                    清除路线
                </div>
                <div class="btn search-line" onclick="naviAndDrawLine()">
                    搜索路线
                </div>
            </div>
            <div class="query-list"></div>
        </div>
    </div>
</body>

<script>
    // 模拟导肮相关参数
    var simulateOptions = {
        speed: 60,               // 模拟导航定位图标行进的速度, 单位m/s。默认7m/s。
        followPosition: true,   // 模拟导航中在位置发生变化时, 地图是否跟随位置居中显示。默认true。
        followAngle: false,     // 模拟导航中在方向发生变化时, 地图是否跟随方向变化, 保持路线朝向屏幕上方。 默认false。
        changeTiltAngle: true,  // 模拟导航中楼层发生变化时是否改变地图的倾斜角度, 并执行动画。默认为true。
        zoom: 21,               // 模拟导航开始时地图的显示缩放级别, 默认值为21, 表示1:282的地图比例尺。
        maxZoom: 22,            // 模拟导航开始时地图的显示最大缩放级别, 默认值为22, 表示1:141的地图比例尺。防止视角过近。
    };

    var map;
    var searchAnalyser; // 搜索分析对象
    var routeAnalyser;           // 路径分析对象
    var floorInfos;          // 楼层信息
    var start;              // 起点
    var dest;               // 终点
    var startMarker, endMarker; // 起点终点图标
    var lineMarker; // 路径线
    var clickPoint; // 点击地图的点坐标
    var mode = fengmap.FMNaviMode.MODULE_SHORTEST; // 最短路径
    var priority = fengmap.FMNaviPriority.PRIORITY_LIFTFIRST; // 直梯优先
    var activeInput; // 活跃的输入框id
    var searchResult; // 搜索结果
    var selectedIndex = -1; // 选中的搜索结果下标
    var navi; // 导航对象
    var isPlay = false
    var options = {
        container: document.getElementById('fengmap'),
        appName: '我的地图1',
        key: '9ab4cc4ca1bbdc561849fa9fa70e2ae6',
        mapID: '1788018353259626498',
        themeID: '1791049180868472833',
        mapZoom: 15,
        viewMode: fengmap.FMViewMode.MODE_2D
    }
    var locationMarker; // 定位marker
    var wayIndex = 0
    var routeName;
    var waypoint = []; // 途经点
    var waypointIndex = 0;
    var wayMarker = [];
    var defaultZoom = 22;


    $('.map-mask').css('display', 'flex')
    map = new fengmap.FMMap(options);
    map.on('loaded', function () {
        floorInfos = map.getFloorInfos()
        // 初始化路径分析类
        routeAnalyser = new fengmap.FMNaviWalkAnalyser({ map: map }, () => {
            console.log('路径分析类创建成功')
        }, () => {
            alert('路径分析类创建失败')
        });
        // 初始化搜索分析对象
        var searchOption = {
            mapID: options.mapID,
            appName: options.appName,
            key: options.key
        }
        searchAnalyser = new fengmap.FMSearchAnalyser(searchOption, () => {
            getName()
        })
    })

    // 通过点击地图获取起点和终点
    map.on('click', function (e) {

        if (e.level) {
            const model = e.targets.find(item => item.type === fengmap.FMType.MODEL)
            if (model) {
                clickPoint = { level: e.level, x: model.x, y: model.y, name: model.name };
                if (activeInput === 'startInput') setStart()
                if (activeInput === 'endInput') setEnd()
            }
        }
    })

    function getName() {
        $.getUrlParam = function (name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)")
            var r = window.location.search.substr(1).match(reg)
            if (r != null) return unescape(r[2])
            return null
        }
        name = $.getUrlParam('name')
        console.log('name', name)
        if (name === 'null') return $('.map-mask').css('display', 'none')

        let searchRequest = new fengmap.FMSearchRequest();
        searchRequest.type = fengmap.FMType.MODEL;
        searchRequest.addCondition({
            'keyword': name
        })
        searchAnalyser.query(searchRequest, (result) => {
            console.log('a', result);
            const data = result || []
            const model = data[0]
            if (!model) return
            clickPoint = { level: model.level, x: model.center.x, y: model.center.y, name: model.name }
            setEnd()
            $('.map-mask').css('display', 'none')
        });
    }

    // 设置起点图标
    function setStart() {
        if (locationMarker) {
            locationMarker.remove();
            locationMarker = null;
        }
        // 清除原来的起点图标
        if (startMarker) {
            startMarker.remove()
        }
        start = { ...clickPoint }
        var marker = new fengmap.FMImageMarker({
            url: '/fengMap/assets/start.png',
            x: clickPoint.x,
            y: clickPoint.y,

        });
        var level = clickPoint.level
        var floor = map.getFloor(level);
        marker.addTo(floor);
        startMarker = marker;
        setCenterAndZoom(clickPoint)

        $('#startInput').val(start.name || '地图选点')

    }

    // 设置终点图标和信息
    function setEnd() {
        if (locationMarker) {
            locationMarker.remove();
            locationMarker = null;
        }
        // 清除原来的终点图标
        if (endMarker) {
            endMarker.remove()
        }
        dest = { ...clickPoint }
        var marker = new fengmap.FMImageMarker({
            url: '/fengMap/assets/end.png',
            x: clickPoint.x,
            y: clickPoint.y,

        });
        var level = clickPoint.level
        var floor = map.getFloor(level);
        marker.addTo(floor);
        endMarker = marker
        setCenterAndZoom(clickPoint)

        $('#endInput').val(dest.name || '地图选点')
    }

    // 添加途经点图标
    function addWaypointMarker() {
        const item = waypoint[waypointIndex - 1]
        const marker = new fengmap.FMImageMarker({
            url: '/fengMap/assets/waypoint.png',
            x: item.x,
            y: item.y,

        });
        const level = item.level
        const floor = map.getFloor(level);
        marker.addTo(floor);
        setCenterAndZoom(item);
        wayMarker[waypointIndex - 1] = marker;
    }

    // 交换起终点
    function onExchange() {
        let temp = start;
        start = dest;
        dest = temp;
        if (!dest || !start) return;
        temp = $('#startInput').val()
        const endValue = $('#endInput').val()
        $('#endInput').val(temp)
        $('#startInput').val(endValue)
        clickPoint = start
        setStart()
        clickPoint = dest
        setEnd()
    }

    // 暂停或者播放轨迹
    function pauseOrPlay() {
        if (isPlay) {
            $('.btn-operate').html('继续')
            navi.pause();
        } else {
            $('.btn-operate').html('暂停')
            navi.resume();
        }
        isPlay = !isPlay

    }

    // 平移地图及放大层级
    function setCenterAndZoom(data) {
        map.setCenter({ x: data.x, y: data.y, level: data.level || 1 })
        map.setZoom({ zoom: defaultZoom })

        // 失去输入框焦点
        activeInput = ''
        $('input').blur()
    }

    // 清除地图所有元素
    function clearAll() {
        isPlay = false
        $('.btn-operate').html('暂停')
        $('#startInput').val('')
        $('#endInput').val('')
        $('#navi_result').css('display', 'none')
        start = null;
        dest = null;
        if (startMarker) {
            startMarker.remove()
            startMarker = null
        }
        if (endMarker) {
            endMarker.remove()
            endMarker = null
        }
        if (lineMarker) {
            lineMarker.remove()
            lineMarker = null
        }
        if (navi) {
            navi.stop()
            navi.clearAll()
        }
        if (locationMarker) {
            locationMarker.remove();
            locationMarker = null;
        }
        wayMarker.forEach((item, index) => {
            if (item) {
                item.remove()
                item = null
            }
        })
        $('.middle-box').html('')
        wayMarker = []
        waypoint = []
        waypointIndex = 0
        wayIndex = 0
    }

    // 分析路径，绘制路线
    function naviAndDrawLine() {
        if (!start || !dest) {
            return;
        }
        if (lineMarker) {
            lineMarker.remove()
        }

        console.log('way', waypoint);
        const request = { start, dest, mode, priority, viapoints: waypoint }
        routeAnalyser.route(request, function (result) {
            segments = [];
            let subs = result.subs;
            var segment = new fengmap.FMSegment();
            for (let index = 0; index < subs.length; index++) {
                const leg = subs[index];
                if (leg.levels[0] === leg.levels[1]) {
                    leg.waypoint.points.forEach(point => {
                        point.z = 0.5;
                    });
                    if (segment.points) {
                        let points = [];
                        points.push(...leg.waypoint.points);
                        points.splice(0, 1);
                        segment.points = segment.points.concat(points);
                    } else {
                        segment.points = leg.waypoint.points;
                    }
                    segment.level = leg.levels[0];
                    if (index == subs.length - 1) {
                        segments.push(segment);
                    }
                } else {
                    segments.push(segment);
                    segment = new fengmap.FMSegment();
                }
            }

            line = new fengmap.FMLineMarker({
                segments: segments,
                smooth: true
            })
            line.addTo(map)
            lineMarker = line

            naviRoute()
        })
    }

    /* 根据起终点进行路径规划并绘制路径线 */
    function naviRoute() {
        // 清空导航类中的起始点标注, 定位标注及当前路线标注。

        if (navi) {
            navi.clearAll();
        }

        navi = new fengmap.FMNavigationWalk({
            map: map,
            analyser: routeAnalyser,
            locationMarkerUrl: '/fengMap/assets/bluedot-arrow.png',
            locationMarkerSize: 48,
            lineMarkerHeight: 0.5,
            locationMarkerHeight: 0.5
        });
        // 设置起终点
        navi.setStartPoint(start);
        navi.setDestPoint(dest);
        // 导航分析
        navi.route(
            {
                mode: fengmap.FMNaviMode.MODULE_BEST,
                priority: fengmap.FMNaviPriority.PRIORITY_DEFAULT,
                viapoints: waypoint
            },
            function (result) {
                // 导航分析成功回调
                var line = navi.drawNaviLine();
                // 自适应路线全览
                navi.overview({
                    ratio: 1.5
                }, function () {
                    console.log('自适应全览动画结束回调');
                    navi.simulate(simulateOptions);
                });
            }, function (result) {
                // 导航分析失败回调
                console.log("failed", result);
            }
        );
    }

    // 顶部输入
    $('#queryId').on('input propertychange', function () {
        activeInput = 'queryInput'
        const inputValue = $('#queryId').val();
        searchModel(inputValue)
    })
    // 起点输入
    $('#startInput').on('input propertychange', function () {
        activeInput = 'startInput'
        const inputValue = $('#startInput').val();
        searchModel(inputValue)
    })
    //终点输入
    $('#endInput').on('input propertychange', function () {
        activeInput = 'endInput'
        const inputValue = $('#endInput').val();
        searchModel(inputValue)
    })
    // 起点输入
    $('#startInput').on('focus', function () {
        activeInput = 'startInput'
    })
    //终点输入
    $('#endInput').on('focus', function () {
        activeInput = 'endInput'
    })
    // 顶部输入
    $('#queryId').on('focus', function () {
        activeInput = 'queryInput'
    })

    function queryList() {

    }

    // 关键字查询
    function searchModel(keyword) {
        if (activeInput === 'queryInput') {
            $('.query-top-list').html(``)
            if (!keyword || keyword === '') return $('.query-top-list').css('display', 'none');
            let searchRequest = new fengmap.FMSearchRequest();
            searchRequest.type = fengmap.FMType.MODEL;
            searchRequest.addCondition({
                'keyword': keyword
            })
            searchAnalyser.query(searchRequest, (result) => {
                searchResult = result || [];
                searchResult.forEach(function (item, index) {
                    const node = $(`<div>${item.name}</div>`)
                    node.click(function () { onResultSelected(index) })
                    $('.query-top-list').append(node)
                })
                $('.query-top-list').css('display', 'block')

            });
        } else {
            $('.query-list').html(``)
            if (!keyword || keyword === '') return $('.query-list').css('display', 'none');
            var searchRequest = new fengmap.FMSearchRequest();
            searchRequest.type = fengmap.FMType.MODEL;
            searchRequest.addCondition({
                'keyword': keyword
            })
            searchAnalyser.query(searchRequest, (result) => {
                searchResult = result || [];
                searchResult.forEach(function (item, index) {
                    const node = $(`<div>${item.name}</div>`)
                    node.click(function () { onResultSelected(index) })
                    $('.query-list').append(node)
                })
                $('.query-list').css('display', 'block')

            });
        }

    }

    // 选中搜索结果
    function onResultSelected(index) {
        selectedIndex = index;
        const model = searchResult[index]
        if (activeInput === 'queryInput') {
            $('.query-top-list').css('display', 'none')
            $('.query-top-list').html(``)
            $('#queryId').val(model.name)
            addLocationMarker(model)
        } else {
            $('.query-list').css('display', 'none')
            $('.query-list').html(``)
            clickPoint = { level: model.level, x: model.center.x, y: model.center.y, name: model.name }
            if (activeInput === 'startInput') {
                setStart()
            } else if (activeInput === 'endInput') {
                setEnd()
            } else if (activeInput === 'wayInput') {
                waypoint[waypointIndex - 1] = { ...clickPoint }
                $(`#waypoint${waypointIndex}`).val(clickPoint.name)
                if (wayMarker[waypointIndex - 1]) {
                    wayMarker[waypointIndex - 1].remove()
                    wayMarker[waypointIndex - 1] = null
                }
                addWaypointMarker()
            }
        }

        console.log(waypoint)
        searchResult = []
    }

    // 顶部搜索
    function queryItem() {
        const inputValue = $('#queryId').val();
        if (!inputValue || !searchResult.length) return $('.query-top-list').css('display', 'none')
        onResultSelected(0)
    }

    // 顶部清除
    function clearQuery() {
        $('#queryId').val('')
        if (locationMarker) {
            locationMarker.remove();
            locationMarker = null;
        }
    }

    // 添加定位点标注
    function addLocationMarker(item) {
        clearAll()
        locationMarker = new fengmap.FMLocationMarker({
            size: 23,
            url: '/fengMap/assets/location.png',
            x: item.center.x,
            y: item.center.y,
            level: item.level
        });

        locationMarker.addTo(map);
        setCenterAndZoom({ x: item.center.x, y: item.center.y, level: item.level });
    }

    function addLine() {
        wayIndex += 1
        const node = `<div class="guide-point guide-middle guide-middle${wayIndex}"><input placeholder="请输入途经点名称" id="waypoint${wayIndex}" class="waypoint" onclick="wayPointSelect(${wayIndex})" /><img src="/fengMap/assets/reduce.png" alt="" class="change-img" onclick="reduceLine(${wayIndex})"  /></div>`
        $('.middle-box').append(node)
    }

    function reduceLine(index) {
        console.log(index);
        const thisNode = document.querySelector(`.guide-middle${index}`);
        const val = $(`#waypoint${index}`).val()
        waypoint = waypoint.filter((item) => item.name !== val)
        console.log(waypoint)
        thisNode.parentNode.removeChild(thisNode);
        if (wayMarker[index - 1]) {
            wayMarker[index - 1].remove()
            wayMarker[index - 1] = null
        }
        wayIndex -= 1
    }

    // 途径点搜索
    function wayPointSelect(index) {
        waypointIndex = index
        $(`#waypoint${index}`).on('input propertychange', function () {
            activeInput = 'wayInput'
            const inputValue = $(`#waypoint${index}`).val();
            searchModel(inputValue)
        })

    }
</script>
<style>
    @-webkit-keyframes rotation {

        from {
            -webkit-transform: rotate(0deg);
        }

        to {
            -webkit-transform: rotate(360deg);
        }

    }

    body {
        margin: 0;
    }

    .guide-box {
        position: relative;
        width: 100%;
        height: 100vh;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        background-color: #fff;
    }

    .map-mask {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: none;
        justify-content: center;
        align-items: center;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 999999;
    }

    .map-mask .loading {
        width: 64px;
        height: 64px;
        background: url('/fengMap/assets/loading.png') no-repeat center;

        -webkit-transform: rotate(360deg);
        animation: rotation 3s linear infinite;
        -moz-animation: rotation 3s linear infinite;
        -webkit-animation: rotation 3s linear infinite;
        -o-animation: rotation 3s linear infinite;

    }

    .guide-search {
        box-sizing: border-box;
        position: absolute;
        top: 0;
        left: 0;
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        padding: 10px 15px;
        background-color: #fff;
        box-shadow: 0 5px 6px rgba(0, 0, 0, 0.2);
        z-index: 99999;
    }

    .ipt_search {
        position: relative;
        display: inline-block;
        width: calc(100% - 100px);
        height: 40px;
        padding-left: 10px;
        text-align: left;
        color: #333;
        background-color: #f5f5f5;
        border: 2rpx solid #EEEEEE;
    }

    .search {
        color: #2C93ED;
    }

    .clear {
        color: orangered;
    }

    .container {
        flex: 1
    }

    .guide-line {
        box-sizing: border-box;
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: auto;
        padding: 10px 6px;
        border-radius: 8px 8px 0 0;
        background-color: #fff;
        box-shadow: 0 -5px 6px rgba(0, 0, 0, 0.2);
    }

    .guide-main {
        position: relative;
        width: 100%;
    }

    .exchange-img {
        position: absolute;
        top: 50%;
        right: 16px;
        transform: translateY(-50%);
        width: 18px;
        height: 18px;
    }

    .guide-point {
        position: relative;
        width: calc(100% - 80px);
        padding: 10px 0 10px 30px;
        border-bottom: 1px solid #F5F5F5;
    }

    .guide-point input {
        height: 30px;
        width: calc(100% - 40px);
        padding-left: 10px;
        background-color: #fff;
    }

    .guide-point img {
        position: absolute;
        top: 50%;
        right: 0;
        transform: translateY(-50%);
        width: 20px;
        height: 20px;
    }

    .guide-point::before {
        content: '';
        display: inline-block;
        width: 6px;
        height: 6px;
        position: absolute;
        top: 50%;
        left: 12px;
        transform: translateY(-50%);
        border-radius: 50%;
    }

    .change-img {
        position: absolute;
        top: 50%;
        right: 16px;
        transform: translateY(-50%);
    }

    .guide-start::before {
        border: 2px solid #7ed321;
    }

    .guide-middle::before {
        border: 2px solid royalblue;
    }

    .guide-end::before {
        border: 2px solid #ff4c3f;
    }

    .guide-end {
        border-bottom: none;
    }

    .line-btns {
        box-sizing: border-box;
        width: 100%;
        margin-top: 6px;
        padding-right: 20px;
        display: flex;
        justify-content: flex-end;
    }

    .btn {
        margin-left: 8px;
        padding: 8px 10px;
        color: #606266;
        background-color: #F5F5F5;
        border-radius: 8px;
    }

    .search-line {
        color: #fff;
        background-color: #2C93ED;
    }

    .query-top-list {
        display: none;
        box-sizing: border-box;
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translate(-50%, 100%);
        width: 96%;
        height: 200%;
        padding: 6px 10px;
        background-color: #fff;
        border-radius: 6px;
        overflow: auto;
    }

    .query-list {
        display: none;
        box-sizing: border-box;
        position: absolute;
        top: 0;
        left: 50%;
        transform: translate(-50%, -100%);
        width: 96%;
        max-height: calc(100vh - 300px);
        min-height: 100%;
        padding: 6px 10px;
        background-color: #fff;
        border-radius: 6px;
        overflow: auto;
    }

    .query-list div,
    .query-top-list div {
        padding: 4px 0;
        border-bottom: 1px solid #eee;
    }
</style>

</html>